#include <jni.h>
#include <string>
#include "libyuv/convert_argb.h"
#include "ALog.h"
#include <jni.h>


libyuv::RotationMode getRotationMode(int degree) {
    libyuv::RotationMode mode = libyuv::kRotate0;
    switch (degree) {
        case 0:
            mode = libyuv::kRotate0;
            break;
        case 90:
            mode = libyuv::kRotate90;
            break;
        case 180:
            mode = libyuv::kRotate180;
            break;
        case 270:
            mode = libyuv::kRotate270;
            break;
    }
    return mode;
}


extern "C" jint
Java_com_junmeng_libyuv_jni_RotationUtil_rotatePlane(JNIEnv *env, jobject thiz, jbyteArray src,
                                                     jint srcStride, jbyteArray dst, jint dstStride,
                                                     jint width,
                                                     jint height, jint degree) {
    uint8_t *_src = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(src, nullptr));
    uint8_t *_dst = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(dst, nullptr));

    int ret = libyuv::RotatePlane(
            _src,
            srcStride,
            _dst,
            dstStride,//dst_stride_argb
            width,
            height,
            getRotationMode(degree));
    if (ret == 0) {
        LOGI("RotatePlane success");
    } else {
        LOGE("RotatePlane fialed:%d", ret);
    }
    env->ReleaseByteArrayElements(src, reinterpret_cast<jbyte *>(_src), JNI_ABORT);
    env->ReleaseByteArrayElements(dst, reinterpret_cast<jbyte *>(_dst), JNI_ABORT);
    return ret;
}

extern "C" jint
Java_com_junmeng_libyuv_jni_RotationUtil_i420Rotate(JNIEnv *env, jobject thiz, jbyteArray src,
                                                    jint src_width, jint src_height, jbyteArray dst,
                                                    jint degree) {
    uint8_t *_src = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(src, nullptr));
    uint8_t *_dst = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(dst, nullptr));

    int dstWidth = src_width;
    int dstHeight = src_height;
    if (degree == 90 || degree == 270) {
        dstWidth = src_height;
        dstHeight = src_width;
    }
    int ret = libyuv::I420Rotate(
            _src,
            src_width,
            _src + src_width * src_height,
            src_width / 2,
            _src + src_width * src_height * 5 / 4,
            src_width / 2,
            _dst,
            dstWidth,
            _dst + src_width * src_height,
            dstWidth / 2,
            _dst + src_width * src_height * 5 / 4,
            dstWidth / 2,
            src_width,
            src_height,
            getRotationMode(degree));
    if (ret == 0) {
        LOGI("I420Rotate success");
    } else {
        LOGE("I420Rotate fialed:%d", ret);
    }
    env->ReleaseByteArrayElements(src, reinterpret_cast<jbyte *>(_src), JNI_ABORT);
    env->ReleaseByteArrayElements(dst, reinterpret_cast<jbyte *>(_dst), JNI_ABORT);
    return ret;
}

extern "C" jint
Java_com_junmeng_libyuv_jni_RotationUtil_nv12ToI420Rotate(JNIEnv *env, jobject thiz, jbyteArray src,
                                                    jint src_width, jint src_height, jbyteArray dst,
                                                    jint degree) {
    uint8_t *_src = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(src, nullptr));
    uint8_t *_dst = reinterpret_cast<uint8_t *>(env->GetByteArrayElements(dst, nullptr));

    int dstWidth = src_width;
    int dstHeight = src_height;
    if (degree == 90 || degree == 270) {
        dstWidth = src_height;
        dstHeight = src_width;
    }
    int ret = libyuv::NV12ToI420Rotate(
            _src,
            src_width,
            _src + src_width * src_height,
            src_width,
            _dst,
            dstWidth,
            _dst + dstWidth * dstHeight,
            dstWidth / 2,
            _dst + dstWidth * dstHeight * 5 / 4,
            dstWidth / 2,
            src_width,
            src_height,
            getRotationMode(degree));
    if (ret == 0) {
        LOGI("NV12ToI420Rotate success");
    } else {
        LOGE("NV12ToI420Rotate fialed:%d", ret);
    }
    env->ReleaseByteArrayElements(src, reinterpret_cast<jbyte *>(_src), JNI_ABORT);
    env->ReleaseByteArrayElements(dst, reinterpret_cast<jbyte *>(_dst), JNI_ABORT);
    return ret;
}